﻿

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace T13DelegateAndEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 委托
            //委托为空
            Buy buy = null;
            //定义对象
            DelegateBuy d = new DelegateBuy();
            //buy委托对象上有两个功能
            buy = new Buy(d.BuyApple);
            buy += new Buy(d.BuyOrange);
            //调用一次委托，可执行加载的2个功能
            Console.WriteLine(buy("张三"));
            //委托对象作为函数参数
            d.whoBuy("李四", buy);
            //buy对象上去掉某个功能
            buy -= d.BuyApple;
            d.whoBuy("王五", buy);
            //取消委托
            buy = null;
            #endregion

            #region 事件
            //发布者对象
            EventBuy e = new EventBuy();
            //订阅者对象
            MrWang wang = new MrWang();
            MrZhang zhang = new MrZhang();
            //订阅者---注册
            wang.Register(e);
            zhang.Register(e);
            //发布者---发布信息
            e.Issue();
            #endregion

            #region 事件订阅
            Console.WriteLine("请输入您的取款金额：");
            string amount = Console.ReadLine();
            Console.WriteLine("交易成功，请取出银行卡");
            //事件参数
            UserEventArgs user = new UserEventArgs("zzz@126.com", "15279950238", amount);
            SubscribeSystem sub = new SubscribeSystem(new Bank(), user);
            #endregion 
            Console.ReadKey();
        }
    }
}


 //定义委托
    public delegate int Buy(string name);

class DelegateBuy
{
    public int BuyApple(string name)
    {
        Console.WriteLine("{0}买苹果", name);
        return 10;
    }
    public int BuyOrange(string name)
    {
        Console.WriteLine("{0}买橙子", name);
        return 20;
    }

    public void whoBuy(string name, Buy buy)
    {
        buy(name);
    }
}

class EventBuy
{
    //定义委托
    public delegate void BuyEventHnadler();
    //定义事件
    public event BuyEventHnadler OnBuy;

    //事件触发器
    public void Issue()
    {
        if (OnBuy != null)
        {
            Console.WriteLine("水果到了!");
            //触发事件
            OnBuy();
        }
    }
}

//事件的订阅者
class MrZhang
{
    public void Receive()
    {
        Console.WriteLine("张收到信息 ，要买苹果");
    }

    //注册事件
    public void Register(EventBuy e)
    {
        e.OnBuy += Receive;
        e.OnBuy -= Receive;
        //e.OnBuy = Receive;  //事件不允许直接赋值操作
    }
}

//事件的订阅者
class MrWang
{
    public void Receive()
    {
        Console.WriteLine("张收到信息 ，要买橙子");
    }

    //注册事件
    public void Register(EventBuy e)
    {
        e.OnBuy += Receive;
    }
}

 //定义事件参数：观察者关心的内容
    public class UserEventArgs : EventArgs
{
    public string Email;
    public string Mobile;
    public string Amount;

    public UserEventArgs(string email, string mobile, string amount)
    {
        Email = email;
        Mobile = mobile;
        Amount = amount;
    }
}

//事件发布者:银行
public class Bank
{
    //声明委托：银行交易
    public delegate void ProcessTranEventHandler(Object sender, UserEventArgs e);
    //声明事件
    public event ProcessTranEventHandler ProcessTran;

    protected virtual void OnProcessTran(UserEventArgs e)
    {
        if (ProcessTran != null)
        {
            ProcessTran(this, e);
        }
    }

    //触发事件
    public void Process(UserEventArgs e)
    {
        OnProcessTran(e);
    }
}

//事件观察者:电子邮件
public class Email
{
    public static void SendMail(Object sender, UserEventArgs e)
    {
        Console.WriteLine($"向用户邮箱{e.Email}发送邮件：您在{System.DateTime.Now}取款金额为{e.Amount}元"
            );
    }
}

//事件观察者：短信
public class MobileSMS
{
    public static void SendNotification(Object sender, UserEventArgs e)
    {
        Console.WriteLine(
            $"向用户邮箱{e.Mobile}发送短信：您在{System.DateTime.Now}取款金额为{e.Amount}元"
            );
    }
}

//订阅系统：松耦合
public class SubscribeSystem
{
    public SubscribeSystem(Bank bank, UserEventArgs e)
    {
        bank.ProcessTran += Email.SendMail;
        bank.ProcessTran += MobileSMS.SendNotification;
        bank.Process(e);
    }
}